package cn.madis.ymcc.service.impl;

import cn.madis.exception.GlobalException;
import cn.madis.ymcc.domain.MessageSms;
import cn.madis.ymcc.dto.MobilePhoneRegisteredDto;
import cn.madis.ymcc.dto.RedisPhoneCodeDto;
import cn.madis.ymcc.result.JSONResult;
import cn.madis.ymcc.service.IMessageSmsService;
import cn.madis.ymcc.service.IVerifycodeService;
import cn.madis.ymcc.util.AssertUtil;
import cn.madis.ymcc.util.StrUtils;
import cn.madis.ymcc.util.VerifyCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifycodeServiceImpl implements IVerifycodeService {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private IMessageSmsService messageSmsService;

    @Override
    public JSONResult phoneRegister(MobilePhoneRegisteredDto dto) {
        //1.判断参数（图形验证码，key，手机号）
        //1.1 图片验证码校验
        Boolean verifyImgCode = verifyImgCode(dto.getImageCode(),dto.getImageCodeKey());
        AssertUtil.isTrue(verifyImgCode,"图形验证码错误");

        //2.拿到上一次的发送记录
        String key = "phoneCode" + dto.getMobile();
        //3.如果上一次有
        RedisPhoneCodeDto lastCode = (RedisPhoneCodeDto)redisTemplate.opsForValue().get(key);
        //当前时间
        long time1 = new Date().getTime();
        String smsCode = null;
        if (lastCode != null){
            //3.1拿到上一次发送时间判断是否超时60s
            if ((time1 - lastCode.getSendTime())/1000 < 60){
                throw new GlobalException("手速过快，请稍后再试");
            }
                //3.2超时拿到上一次验证码发送
                smsCode = lastCode.getCode();

        }else {
            //4.如果是第一次
            //4.1创建手机验证码
            smsCode = StrUtils.getRandomString(6);
            //5.存手机验证码到redis中
            long time = System.currentTimeMillis();
            redisTemplate.opsForValue().set(key,new RedisPhoneCodeDto(smsCode,time),10, TimeUnit.MINUTES);
        }

        //6.调用短信网关发送验证码
        //SmsUtils.sendMsg(dto.getMobile(),phoneCodecode);
        log.info("手机验证码是"+smsCode);
        //7.存数据到db
        insertSMSSendLog(dto);
        return JSONResult.success();
    }


    /**
     * 图形验证码验证
     */
    public Boolean verifyImgCode(String imageCode, String imageCodeKey) {
        //完善图形验证码验证
        //1.判断参数为空校验
        if(org.springframework.util.StringUtils.isEmpty(imageCodeKey) || org.springframework.util.StringUtils.isEmpty(imageCode)){
            throw new GlobalException("参数为空，请填写");
        }
        //3.判断图形验证码是否存在、是否正确
        Object imageCodeTmp = redisTemplate.opsForValue().get(imageCodeKey);
        if (imageCodeTmp == null){
            throw new GlobalException("图形验证码不存在！");
        }//equalsIgnoreCase
        if (!imageCodeTmp.toString().equalsIgnoreCase(imageCode)){
            throw new GlobalException("图形验证码错误，请重新填写！");
        }
        //造假
        if (StringUtils.equals("5555555",imageCode)){
            return false;
        }
        return true;
    }

    /**
     * 发送短信日志添加
     */
    public void insertSMSSendLog(MobilePhoneRegisteredDto dto) {
        MessageSms messageSms = new MessageSms();
        String mobile = dto.getMobile();
        String imageCode = dto.getImageCode();
        messageSms.setContent(mobile + imageCode);
        messageSms.setSendTime(new Date());
        messageSms.setTitle("用户注册验证码");
        //拿ip
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        messageSms.setIp(request.getRemoteAddr());
        messageSmsService.insert(messageSms);
    }

    /*/**
     * @Title: graph
     * @Description: 发送图片验证码 q
     * @Author: Mr.She
     * @Version: 1.0
     * @Date:  2022/7/6 15:32
     * @Parameters: [imageCodeKey]
     * @Return java.lang.String
     */
    @Override
    public String graph(String imageCodeKey) {
        // 判断key值是否为空 为空抛出自定义异常
        if(org.springframework.util.StringUtils.isEmpty(imageCodeKey)){
            throw new RuntimeException("参数值为空,请检查");
        }
        // 调用字符串工具类 获取四位随机字符
        String code = StrUtils.getComplexRandomString(4);
        // 把key 和随机四位字符 设置到redis中
        redisTemplate.opsForValue().set(imageCodeKey,code,5, TimeUnit.MINUTES);
        // 将code 值变成图形并编码base64
        String base64Str = VerifyCodeUtils.verifyCode(100, 35, code);
        // 返回图形base64码
        return base64Str;
    }
}
